%% Load all training images, and save filtered images.
%% Images shall be resized such that image area size is in an
%LHIPath = 'D:\Projects\AoT\data'
imgFileList= extractLHIImageName(source_img_path_list);
canonicalDistance=11;
fprintf(1,'resize image under canonical distance: %d\n',canonicalDistance);

% now suppose images are stored like:
%{
    I: n by 1 cell, each is a colored image
    S1: filtered S1 maps,n_orient by n
    M1: M1 maps, n_orient by n;
    S2: filtered S2 maps, n_orient by n_length by n;
    M2: filtered M2 maps, n_orient by n_length by n;
    s_width; n by 1: size of map;
    s_height; n by 1: size of map;
    s0_width;
    s0_height;
    PMat: 12 by n, the projection matrix;
    viewMat: 4 by n, the viewing direction matrix;
%}
%% images
n_image= length(imgFileList);
I_color = cell(n_image,1);
I_gray = cell(n_image,1);
Sx = zeros(n_image,1);
Sy = zeros(n_image,1);
Zx = zeros(n_image,1);
Zy = zeros(n_image,1);
PMat = zeros(12,n_image,'single');
viewMat = zeros(3,n_image,'single');
%{
for iFile = 1:n_image
    imgName = [imgFileList(iFile).path '/' imgFileList(iFile).name];
    fprintf('loading image: %s\n',imgName);
    img= imread(imgName);
    
    dims = size(img);
    img = imresize(img,[NaN sy]);
    sx = size(img,1);
    Sx(iFile)=sx;
    Sy(iFile)=sy;

    if size(img,3)==3
        I_color{iFile}=img;
        img = rgb2gray(img);
    else
        fprintf('image not in color: %s', imgName);
    end
    I_gray{iFile}= img;
	
	view = readView(imgFileList(iFile).path,[imgFileList(iFile).name(1:end-3) 'view']);
    PMat(:,iFile) = reshape(view.P,12,1);
    viewMat(:,iFile) = view.cam_dir;
  
    Zx(iFile) = sx/view.height;
    Zy(iFile) = sy/view.width;
    %close
    %testProjection(reshape(view.P,3,4),I_color{iFile},Zx(iFile),Zy(iFile),sx,sy);
    %saveas(gcf,[cachePath '/projection' num2str(iFile) '.png']);
    close;
end
%}

% load image, normalize to canonical size, and save corresponding view
% matrix.
for iFile = 1:n_image
    imgName = [imgFileList(iFile).path '/' imgFileList(iFile).name];
    fprintf('loading image: %s\n',imgName);
    img= imread(imgName);
    view = readView(imgFileList(iFile).path,[imgFileList(iFile).name(1:end-3) 'view']);
    
    % normalize image to canonical size
    Pc = raiseViewPoint(-view.pan/pi*180,view.tilt/pi*180,view.roll/pi*180,canonicalDistance);
    BB_c = testProjection(Pc,[],1,1,300,400); % bounding box under canonical view
    areaC= (BB_c(2)-BB_c(1))*(BB_c(4)-BB_c(3));% bounding box size; 
    BB = testProjection(reshape(view.P,3,4),[],size(img,1)/view.height,size(img,2)/view.width,size(img,1),size(img,2));
    areaB=(BB(2)-BB(1))*(BB(4)-BB(3)); % bounding box in current loaded image
    view_ratio =sqrt (areaC/areaB);
    img = imresize(img,view_ratio);
    close all;

    sx = size(img,1);
    sy = size(img,2);
    Sx(iFile)=sx;
    Sy(iFile)=sy;

    if size(img,3)==3
        I_color{iFile}=img;
        img = rgb2gray(img);
    else
        fprintf('image not in color: %s', imgName);
    end
    I_gray{iFile}= img;
	

    PMat(:,iFile) = reshape(view.P,12,1);
    viewMat(:,iFile) = view.cam_dir;
  
    Zx(iFile) = sx/view.height;
    Zy(iFile) = sy/view.width;
    %close
    %testProjection(reshape(view.P,3,4),I_color{iFile},Zx(iFile),Zy(iFile),sx,sy);
    %saveas(gcf,[cachePath '/projection' num2str(iFile) '.png']);
    close;
end

% create filters
disp(['build filters']);
[allfilter, allsymbol] = makefilter(scale, nOrient);  % generate Gabor filters
C = corr(allfilter, epsilon);
h = (size(allfilter{1}, 1)-1)/2; % half size of Gabor
% filtering
%S1_maps = cell(nOrient,n_image);
%M1_maps = cell(nOrient,n_image);
%S2_maps = cell(nOrient,nLength,n_image);
M2_maps = cell(nLength,nOrient,n_image);

for i_img = 1:n_image
    fprintf('fitlering image %d of %d \n', i_img, n_image);
    
    % create temp memory for filtering
    sx = Sx(i_img); sy = Sy(i_img);
    M1map = cell(nOrient,1); % 1 could be extended to nSacale
    S2map = cell(nLength,nOrient);
    M2map = cell(nLength,nOrient);
    for i_map =1 :numel(M1map);
        M1map{i_map}=NEGMAX + ones(sx,sy,'single');
    end
    for i_map= 1:numel(S2map)
        S2map{i_map}=NEGMAX + ones(sx,sy,'single');
    end
    for i_map= 1:numel(S2map)
        M2map{i_map}=NEGMAX + ones(sx,sy,'single');
    end 
    % S1
    S1map = applyfilterfftsame(I_gray(i_img),allfilter);
    ClocalNormalizeSingle(sx,sy,nOrient,h,...
        localHalfx,localHalfy,S1map,thresholdFactor);
    for i_ori = 1:nOrient
        S1map{i_ori}=gaborSaturation.*(2./(1+exp(-2/gaborSaturation.*S1map{i_ori}))-1);
    end
    
    % M1
    CMax1Single(1,nOrient, h, S1map, M1map,Lrange, Orange, sx,sy);
    % S2
    CSum2Single(1, nOrient,nLength,1, M1map,S2map,sx,sy,h,lambda,logZ);
    % M2
    CMax2Single(1, nOrient, h, nLength, 1, S2map,M2map,...
        Lrange2, Orange2, 0,LenRange2,sx,sy);
    
    % put into designed data structure
    %    for i_map =1 :numel(M1map);
    %       M1_maps{i_map,i_img}=S1map{i_map}+0.0;
    %       S1_maps{i_map,i_img}=S1map{i_map}+0.0;
    %    end
    for i_map = 1:numel(S2map);
        %        S2_maps{i_map+(i_img-1)*nLength*nOrient} = S2map{i_map} + 0.0;
        M2_maps{i_map+(i_img-1)*nLength*nOrient} = M2map{i_map} + 0.0;
    end
    out_name= [cachePath '/S1maps_' num2str(i_img) '.mat'];
    save(out_name,'S1map');
    
    out_name= [cachePath '/S2maps_' num2str(i_img) '.mat'];
    save(out_name,'S2map');
    
end



%% save the maps into disk
out_name = [cachePath '/filters.mat'];
save(out_name,'C','allsymbol','allfilter');



%% create color maps
color_l_maps = cell(n_image,1);
color_a_maps = cell(n_image,1);
color_b_maps = cell(n_image,1);
ccf = fspecial('average',h);
for i_img = 1:n_image
    % fprintf('converting color image %d of %d \n', i_img, n_image);
    rgb_img = im2single(I_color{i_img});
	lab_img = rgb_img;
	
	%lab-->rgb
    color_l_maps{i_img}=lab_img(:,:,1);
    color_a_maps{i_img}=lab_img(:,:,2);
    color_b_maps{i_img}=lab_img(:,:,3);
    color_l_maps{i_img} = imfilter(color_l_maps{i_img},ccf);	
    color_a_maps{i_img} = imfilter(color_a_maps{i_img},ccf); 
    color_b_maps{i_img} = imfilter(color_b_maps{i_img},ccf);
end
clear lab_img;
clear rgb_img
clear ccf;
clear ct;
out_name = [cachePath '/color_features.mat'];
save(out_name,'color_l_maps','color_a_maps','color_b_maps');
